/*
 *  ELF/Mach-O object file loading
 *
 *  Copyright (c) 2006 Pierre d'Herbemont
 *  Copyright (c) 2010-2011 Tobias Platen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "dyld_private.h"
#include <vector>




std::vector<ImageLoader*> loaders;


void addImage(ImageLoader* l)
{
	loaders.push_back(l);
}

ImageLoader* loaderForPath(char* loader)
{

	std::vector<ImageLoader*>::iterator it;
        for ( it=loaders.begin() ; it < loaders.end(); it++ )
	{
		if((*it)->getInstallname()==loader) return (*it);  
	}
        DYLD_WARN(printf("library not found %s",loader));
	return NULL;
}

extern "C" void preload();
extern "C" int dyld_main(int argc,char** argv)//only works on 32 bit
{
    DYLD_DEBUG(printf("dyld %s %s\n",argv[0],argv[1]));
	if(argv[1]==0)
    {
	printf("usage: dyld program arguments\n");
	exit(1);
    }
	
	
	//preload();
        //inject lazy loading buildin dylibs 
	addImage(new ImageLoaderElf(NULL,"libringo.so","/usr/lib/libSystem.B.dylib"));
	addImage(new ImageLoaderElf(NULL,"libobjc.so","/usr/lib/libobjc.A.dylib"));
	addImage(new ImageLoaderElf(NULL,"libgcc_s.so.1","/usr/lib/libgcc_s.1.dylib"));
	addImage(new ImageLoaderElf(NULL,"libAppKit.so.0","Cocoa"));//hack
	addImage(new ImageLoaderElf(NULL,"libFoundation.so.0","/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation"));//hack
	addImage(new ImageLoaderElf(NULL,"libFoundation.so.0","/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"));//hack
	if(getenv("DYLD_DEBUG"))
	{
            int pid=fork();
            if(pid==0)
            {
                char ppid[32];
                sprintf(ppid,"--pid=%i",getppid());
                execle("/usr/bin/gdb","/usr/bin/gdb",ppid,argv[0],0,environ);
                fprintf(stderr,"faild to start gdb\n");
                exit(0);
            }
            sleep(1);
	}
	ImageLoader* l=load_object(argv[1]);
	if(l==0) exit(-1);//not found
	l->loadDylibs();
	l->link();
	int i;
	int entry=(int)l->loadThread();
        //shift arguments 
        //for(i=0;i<argc;i++)
        //{
    	//   argv[i]=argv[i+1];
        //}
	DYLD_DEBUG(printf("entry %x\n",entry));
	return entry;


    
}
